package com.ddw.wotcg.server.controllers;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletException;

import com.ddw.wotcg.server.utils.FieldValidation;
import com.ddw.wotcg.server.utils.Hasher;
import com.ddw.wotcg.server.utils.RequestHelper;
import com.ddw.wotcg.server.utils.TemplateHelper;
import com.ddw.wotcg.server.utils.User;
import com.ddw.wotcg.server.utils.UserHelper;

@SuppressWarnings("serial")
public class SignUpController extends ControllerBase {
	
	public void complete() throws IOException, ServletException {
		final Map<String, Object> root = new HashMap<String, Object>();
		final Map<String, String> cookies = RequestHelper
				.parseCookies(this.request);
		final UUID session = RequestHelper.getSession(cookies);
		final User user = UserHelper.bySession(session);
		
		// If user is logged in then redirect them
		if (user != null) {
			this.response.sendRedirect("/home");
			return;
		}
		
		TemplateHelper.appendPageData(root, "Sign Up Complete");
		TemplateHelper.appendUserData(root, user);
		
		TemplateHelper.callTemplate(this.config, this.response,
				"/signup/complete.ftl", root);
	}
	
	public void index() throws IOException, ServletException {
		final Map<String, Object> root = new HashMap<String, Object>();
		final Map<String, String> cookies = RequestHelper
				.parseCookies(this.request);
		final UUID session = RequestHelper.getSession(cookies);
		final User user = UserHelper.bySession(session);
		
		// If user is logged in then redirect them
		if (user != null) {
			this.response.sendRedirect("/home");
			return;
		}
		
		TemplateHelper.appendPageData(root, "Sign Up");
		TemplateHelper.appendUserData(root, user);
		
		// Populate defaults
		root.put("email", "");
		root.put("emailInvalid", null);
		root.put("username", "");
		root.put("usernameInvalid", null);
		root.put("password", "");
		root.put("passwordInvalid", null);
		
		// If its a post request then try to create account
		if ("POST".equals(this.request.getMethod())) {
			if (signUp(root)) {
				this.response.sendRedirect("/signup/complete");
				return;
			}
		}
		
		TemplateHelper.callTemplate(this.config, this.response,
				"/signup/index.ftl", root);
	}
	
	/**
	 * Attempt to validate and signup a user
	 * 
	 * @param root
	 *            the root map to append to for the template
	 * @return a flag indicating if the user was signed up
	 */
	private boolean signUp(Map<String, Object> root) {
		// Get the parameters
		final String email = this.request.getParameter("email");
		final String username = this.request.getParameter("playerName");
		String password = this.request.getParameter("password");
		
		// Post back variables for page
		root.put("email", email);
		root.put("username", username);
		root.put("password", password);
		
		// Check email
		if (FieldValidation.validEmail(email) == false) {
			root.put("emailInvalid",
					"Please enter a valid email address e.g. someone@mail.com");
			return false;
		}
		
		// Check username
		if (FieldValidation.validUsername(username) == false) {
			root.put("usernameInvalid",
					"Please enter a valid player name, only letters and numbers");
			return false;
		}
		
		// Check password
		if (FieldValidation.validPassword(password) == false) {
			root.put(
					"passwordInvalid",
					"Please enter a valid password, at least six characters, must include one letter and one number");
			return false;
		}
		
		// Find user by email address
		User user = UserHelper.byEmail(email);
		
		// If user exist's then flag an error
		if (user != null) {
			root.put(
					"emailInvalid",
					"The email address is already signed up, try <a href=\"/signin\">signing in</a>");
			return false;
		}
		
		// Find user by user name
		user = UserHelper.byUsername(username);
		
		// If user exist's then flag an error
		if (user != null) {
			root.put("usernameInvalid",
					"The player name is already taken, try <a href=\"/signin\">signing in</a>");
			return false;
		}
		
		// We are now safe to create the user record, hash the password
		password = Hasher.hash(password);
		
		// Create user
		user = new User();
		user.username = username;
		user.email = email;
		user.password = password;
		user.created = new Date();
		UserHelper.save(user);
		return true;
	}
	
}
